//COMMANDS --------------------------------
_dss_editor._command.cmdstack = [];

function DSCCommand() {

    this.canExecute = function() {
        return true;
    };

    this.execute = function() {
        alert('do command');
    };

    this.doCommand = function() {
        if (this.canExecute()) {
            return this.execute();
        }
    };

    this.undoCommand = function() {

    };

    this.redoCommand = function() {

    };
};

// ADDCOMMAND ------------------
function AddCommand(canvas, child) {
    this.parent = canvas.onDiagram;
    this.child = child;
    this.canvas = canvas;
    this.oldparent = this.child.parent;
    this.oldRect = this.child.getRectangle();
};
AddCommand.prototype = new DSCCommand();
AddCommand.prototype.canExecute = function() {
    if (this.parent == this.child) {
        return false;
    }
    while (this.parent.hasOwnProperty('parent')) {
        if (this.parent.parent == this.child) {
            return false;
        }
        this.parent = this.parent.parent;
    }
    this.parent = this.canvas.onDiagram;
    if (this.child.hasOwnProperty('parent')) {
        if (this.child.parent == this.parent) {
            return false;
        }
    } else if (this.parent == this.canvas.sys) {
        return false;
    }
    return true;
};
AddCommand.prototype.execute = function() {
	if (ArrayTool.isArrayInstance(this.child)) {
		this.parent.addChild(this.child.parent);
	} else {
		this.parent.addChild(this.child);
	}
	if (this.child.newBounds) {
		var rectangle = _dss_editor._toolkit.translateToRelative(this.child, this.child.newBounds);
		if (this.child.type == EXITPOINT || this.child.type == PRECOND || this.child.type == POSTCOND) {
			rectangle = diagram.newBounds;
		}
		this.rectangle = rectangle;
		new ChangeConstraintCommand(this.child, rectangle).doCommand();		
	}
	this.child.updateLinks();
};
AddCommand.prototype.undoCommand = function(eventObj) {
    var canvas = eventObj.canvas;
    if (ArrayTool.isArrayInstance(this.child)) {
        this.oldparent.addChild(this.child.oldparent);
    } else {
        this.oldparent.addChild(this.child);
    }
    this.child.setRectangle(this.oldRect);
    this.child.updateLinks();
    canvas.removeSelectionSystem();
};
AddCommand.prototype.redoCommand = function(eventObj) {
	var canvas = eventObj.canvas;
	if(ArrayTool.isArrayInstance(this.child)) {
		this.parent.addChild(this.child.parent);
	} else {
		this.parent.addChild(this.child);
	}
	this.child.setRectangle(this.rectangle);
	this.child.updateLinks();
};

// REMOVE COMMAND
function RemoveCommand(canvas, parent, child) {
    this.parent = parent;
    this.child = child;
    this.canvas = canvas;
}

RemoveCommand.prototype = new DSCCommand();
RemoveCommand.prototype.execute = function() {
	this.child.clearHandles();
	var links = _dss_editor._toolkit.getSystemAllInnerLinks(this.child);	
	this.links = links;
	var linksLength = links.length;
	for (var i = 0; i < linksLength; i ++) {		
		var link = links[i];
		if(link.getFromSystem().style !== LINK) {
				link.fromSystem.removeLinkFrom(link);
				link.toSystem.removeLinkTo(link);
				link.clearHandles();
				this.canvas.removeLink(link);
		} else {
			if(link.linkFrom){
				var linkLinkFromLength = link.linkFrom.length;
				for (var j = 0; j < linkLinkFromLength; j ++) {
					var l = link.linkFrom[j];
					l.toSystem.removeLinkTo(l);
					this.canvas.removeLink(l);
					doRemoveCommand(this.canvas, l);
				}
			}
			link.toSystem.removeLinkTo(link);
			this.canvas.removeLink(link);
		}
	}
	if (ArrayTool.isArrayInstance(this.child)) {
		this.parent.removeInstance(this.child);
	} else {
		this.parent.removeChild(this.child);
	}
};
function doRemoveCommand(canvas, link) {
    if (link) {
        if (link.linkFrom != undefined) {
            var linkLinkFromLength = link.linkFrom.length;
            for (var j = 0; j < linkLinkFromLength; j++) {
                var l = link.linkFrom[j];
                l.toSystem.removeLinkTo(l);
                // link.removeLinkFrom(l);
                canvas.removeLink(l);
                doRemoveCommand(canvas, l);
            }
        }
    }
}

RemoveCommand.prototype.undoCommand = function(eventObj) {
    if (ArrayTool.isArrayInstance(this.child)) {
        this.parent.addChild(this.child.parent);
    } else {
        this.parent.addChild(this.child);
    }
    var canvas = eventObj.canvas;
    var linksLength = this.links.length;
    for (var i = 0; i < linksLength; i++) {
        var link = this.links[i];
        if (this.links[i].getFromSystem().getType) {
            var link = this.links[i];
            // if (link.linkFrom != undefined) {
            // undoLink(link, this.canvas);
            // }
            link.fromSystem.addLinkFrom(link);
            link.toSystem.addLinkTo(link);
            canvas.addLink(link);
        } else {
            if (link.linkFrom != undefined) {
                undoLink(link, this.canvas);
            }
            link.toSystem.addLinkTo(link);
            this.canvas.addLink(link);
        }
    }
};
function undoLink(link, canvas) {
    var linkLength = link.linkFrom.length;
    for (var i = 0; i < linkLength; i++) {
        var l = link.linkFrom[i];
        l.toSystem.addLinkTo(l);
        canvas.addLink(l);
        if (l.linkFrom) {
            undoLink(l, canvas);
        }
    }
}
RemoveCommand.prototype.redoCommand = function(eventObj) {
	this.doCommand();
};

// REMOVE LINK COMMAND
function RemoveLinkCommand(canvas, link) {
    this.link = link;
    this.canvas = canvas;
}
RemoveLinkCommand.prototype = new DSCCommand();
RemoveLinkCommand.prototype.execute = function() {
    if (this.link.linkFrom != undefined) {
        for (var i = 0; i < this.link.linkFrom.length; i++) {
            var l = this.link.linkFrom[i];
            this.link.toSystem.removeLinkTo(l);
            this.canvas.removeLink(l);
            doRemoveLinkCommand(this.canvas, l);
        }
    }
    this.link.fromSystem.removeLinkFrom(this.link);
    this.link.toSystem.removeLinkTo(this.link);
    this.link.clearHandles();
    this.canvas.removeLink(this.link);
};
function doRemoveLinkCommand(canvas, link) {
    if (link.linkFrom != undefined) {
        for (var i = 0; i < link.linkFrom.length; i++) {
            var l = link.linkFrom[i];
            link.toSystem.removeLinkTo(l);
            canvas.removeLink(l);
            doRemoveLinkCommand(canvas, l);
        }
    }
}

RemoveLinkCommand.prototype.undoCommand = function(eventObj) {
    //	还要恢复线上线，等一个实现后加一个递归的就可以了
    var canvas = eventObj.canvas;
    if (this.link.linkFrom != undefined) {
        var linkFromLength = this.link.linkFrom.length;
        for (var i = 0; i < linkFromLength; i++) {
            var link = this.link.linkFrom[i];
            link.toSystem.addLinkTo(link);
            canvas.addLink(link);
            undoRemoveLinkCommand(canvas, link);
        }
    }
    this.link.toSystem.addLinkTo(this.link);
    this.link.fromSystem.addLinkFrom(this.link);
    canvas.addLink(this.link);
};
function undoRemoveLinkCommand(canvas, link) {
    if (link.linkFrom != undefined) {
        for (var i = 0; i < link.linkFrom.length; i++) {
            var l = link.linkFrom[i];
            canvas.addLink(l);
            l.toSystem.addLinkTo(l);
            undoRemoveLinkCommand(canvas, l);
        }
    }
}
RemoveLinkCommand.prototype.redoCommand = function (eventObj){
	this.doCommand();
};

// CHANGE CONSTRAINT COMMAND
function ChangeConstraintCommand(diagram, rectangle) {
    this.diagram = diagram;
    this.rectangle = rectangle;
}

ChangeConstraintCommand.prototype = new DSCCommand();
ChangeConstraintCommand.prototype.execute = function() {
	this.beforeRectangle = this.diagram.getRectangle();
	if (this.diagram.type == EXITPOINT || this.diagram.type == PRECOND || this.diagram.type == POSTCOND) {
		var angle = _dss_editor._model.link.genAngle(this.diagram.parent, this.rectangle);
		this.rectangle = _dss_editor._toolkit.calculatePointBounds(this.rectangle, this.diagram.parent);
		this.rectangle.angle = angle;
	}
	if (this.diagram.style == SYSTEM && !this.diagram.isShowContent()) {
		this.rectangle.h = this.diagram.showInfo.rectangle.h;
	}
	this.diagram.setRectangle(this.rectangle);
};
ChangeConstraintCommand.prototype.undoCommand = function(eventObj) {
	this.diagram.setRectangle(this.beforeRectangle);
	_dss_editor._model.system.refreshSystemSelectionHandle(eventObj.canvas);
};
ChangeConstraintCommand.prototype.redoCommand = function(eventObj) {
	this.doCommand();
	_dss_editor._model.system.refreshSystemSelectionHandle(eventObj.canvas);
};

// COPY
function CopyCommand(canvas) {
    this.diagrams = canvas.selectionDiagrams;
    this.canvas = canvas;
}

CopyCommand.prototype = new DSCCommand();
CopyCommand.prototype.canExecute = function() {
    if (this.canvas.hasOwnProperty('input')) {
        return false;
    }
    if (this.diagrams.length == 0) {
        return false;
    };
    return true;
};
CopyCommand.prototype.execute = function() {
    clipboard.pop();
    for (var i in this.diagrams) {
        var diagram = this.diagrams[i];
        clipboard.push(diagram);
    }
    // cmds_dss_editor._command.cmdstacktack.push(this);
};

// PASTE
function PasteCommand(location, parent, canvas) {
    this.location = location;
    this.parent = parent;
    this.canvas = canvas;
    this.completePasteLinks = function(system) {
        for (var i in system.getChildren()) {
            var sub = system.getChildren()[i];
            for (var j in sub.getLinkTo()) {
                var link = sub.getLinkTo()[j];
                link.to = sub.getFullName();
                _dss_editor._model.link.initLink(canvas, link);
                this.canvas.addLink(link);
            }
            for (var j in sub.getLinkFrom()) {
                var link = sub.getLinkFrom()[j];
                link.from = sub.getFullName();
                _dss_editor._model.link.initLink(canvas, link);
                this.canvas.addLink(link);
            }
            this.completePasteLinks(sub);
        }
    };
}
PasteCommand.prototype = new DSCCommand();
PasteCommand.prototype.canExecute = function() {
    if (this.canvas.hasOwnProperty('input')) {
        return false;
    }
    if (clipboard.length > 0) {
        return true;
    }
    ;
    return false;
};
PasteCommand.prototype.execute = function() {
    var system = clipboard[0];
    var clonedModel = _dss_editor._toolkit.clone(system);
    var newDiagram = clonedModel.system;
    var newLinks = clonedModel.links;
    // _dss_editor._model.system.initDiagram(newDiagram);
    newDiagram.setName(newDiagram.getName() + '_copy');
    this.parent.addChild(newDiagram);

    var rect = {
        x : 0,
        y : 0,
        w : 0,
        h : 0
    };
    rect.w = newDiagram.getRectangle().w;
    rect.h = newDiagram.getRectangle().h;
    rect.x = this.location.x;
    rect.y = this.location.y;
    rect = _dss_editor._toolkit.translateToRelative(newDiagram, rect);
    newDiagram.setRectangle(rect);
    for (var i = 0; i < newLinks.length; i++) {
        var link = newLinks[i];
        if (link) {
            this.canvas.addLink(link);
        }
    }
    this.diagram = newDiagram;
    this.links = newLinks;
};
PasteCommand.prototype.undoCommand = function(eventObj) {
    var canvas = eventObj.canvas;
    var system = this.diagram;
    system.clearHandles();
    if (ArrayTool.isArrayInstance(system)) {
        system.parent.removeInstance(system);
    } else {
        system.parent.removeChild(system);
    }
    canvas.removeSelectionSystem();
    for (var i = 0; i < this.links.length; i++) {
        var l = this.links[i];
        this.canvas.removeLink(l);
    }
};
PasteCommand.prototype.redoCommand = function(eventObj) {
	this.doCommand();
};

// SHADOW
function EditShadowCommand(diagram, shadow) {
    this.diagram = diagram;
    this.shadow = shadow;
}

EditShadowCommand.prototype = new DSCCommand();
EditShadowCommand.prototype.execute = function() {
    this.diagram.setHasShadow(this.shadow);
    // _dss_editor._command.cmdstack.push(this);
};
EditShadowCommand.prototype.undoCommand = function() {
    if (this.shadow === NO) {
        this.diagram.setHasShadow(YES);
    } else {
        this.diagram.setHasShadow(NO);
    }
};
EditShadowCommand.prototype.redoCommand = function(){
	this.doCommand();
};

// create
function CreateCommand(type, location, parent) {
    this.type = type;
    this.location = location;
    this.parent = parent;
}
CreateCommand.prototype = new DSCCommand();
CreateCommand.prototype.execute = function() {
    var diagram = _dss_editor._model.system.create(this.type);
    this.parent.addChild(diagram);
    var rectangle = {};
    if (this.type.style == SYSTEM) {
        rectangle = diagram.showInfo.rectangle;
    } else if (this.type.style == POINT) {
        rectangle = diagram.showInfo;
    }
    rectangle.x = this.location.x;
    rectangle.y = this.location.y;

    if (this.type.type != EXITPOINT && this.type.type != PRECOND && this.type.type != POSTCOND) {
        rectangle = _dss_editor._toolkit.translateToRelative(diagram, rectangle);
    }
    new ChangeConstraintCommand(diagram, rectangle).doCommand();
    this.system = diagram;
    return diagram;
    // diagram.parent = this.parent;
};
CreateCommand.prototype.undoCommand = function(eventObj) {
	var canvas = eventObj.canvas;
	var system = this.system;
	system.clearHandles();
	if (ArrayTool.isArrayInstance(system)) {
		system.parent.removeInstance(system);
	} else {
		system.parent.removeChild(system);
	}
	canvas.removeSelectionSystem();
};
CreateCommand.prototype.redoCommand = function(eventObj) {
	var canvas = eventObj.canvas;
	var system = this.system;
	system.clearHandles();
	if(ArrayTool.isArrayInstance(system)){
		system.parent.addInstance(system);
	} else {
		system.parent.addChild(system);
	}
	canvas.removeSelectionSystem();
};

// instantiate
function InstantiateCommand(diagram, instantiate) {
    this.diagram = diagram;
    this.instantiate = instantiate;
}

InstantiateCommand.prototype = new DSCCommand();
InstantiateCommand.prototype.execute = function() {
    this.diagram.setInstantiate(this.instantiate);
    // _dss_editor._command.cmdstack.push(this);
};
InstantiateCommand.prototype.undoCommand = function() {
    // this.diagram.setInstantiate(!this.instantiate);
    if (this.instantiate === NO) {
        this.diagram.setInstantiate(YES);
    } else {
        this.diagram.setInstantiate(NO);
    }
};
InstantiateCommand.prototype.redoCommand = function() {
	this.doCommand();
};

// show label
function EditShowLabelCommand(diagram, showLabel) {
    this.diagram = diagram;
    this.showLabel = showLabel;
}
EditShowLabelCommand.prototype = new DSCCommand();
EditShowLabelCommand.prototype.execute = function() {
    this.diagram.setShowLabel(this.showLabel);
    if (getValue(this.diagram.showInfo.showLabel) == NO) {
        this.diagram.showInfo.rectangle.h -= labelHeight;
        this.diagram.showInfo.rectangle.y += labelHeight;
    } else if (getValue(this.diagram.showInfo.showLabel) == YES) {
        var rectangle = this.diagram.getRectangle();
        rectangle.h += labelHeight;
        rectangle.y -= labelHeight;
        this.diagram.setRectangle(rectangle);
    }
};
EditShowLabelCommand.prototype.undoCommand = function(eventObj) {
    var canvas = eventObj.canvas;
    if (this.showLabel === NO) {
        this.diagram.setShowLabel(YES);
    } else {
        this.diagram.setShowLabel(NO);
    }
    if (getValue(this.diagram.showInfo.showLabel) == NO) {
        this.diagram.showInfo.rectangle.h -= labelHeight;
        this.diagram.showInfo.rectangle.y += labelHeight;
    } else if (getValue(this.diagram.showInfo.showLabel) == YES) {
        var rectangle = this.diagram.getRectangle();
        rectangle.h += labelHeight;
        rectangle.y -= labelHeight;
        this.diagram.setRectangle(rectangle);
    }
    _dss_editor._model.system.refreshSystemSelectionHandle(canvas);
};
EditShowLabelCommand.prototype.redoCommand = function(eventObj) {
	this.doCommand();
	_dss_editor._model.system.refreshSystemSelectionHandle(eventObj.canvas);
};

function EditShowContentCommand(system, showContent) {
    this.system = system;
    this.showContent = showContent;
    this.setLinkVisible = function(superSys) {
        var links = _dss_editor._toolkit.getSystemAllInnerLinks(superSys);
        for (var i = 0; i < links.length; i++) {
            //links[i].updateStatus();
            _dss_editor._model.link.updateStatus.apply(links[i]);
        }
    };
    this.calculateFitSize = function() {
        //var system = arguments[0];
        var canvas = _dss_editor.canvas[_dss_editor.activeCanvas];
        var fitSize = {
            w : system.getRectangle().w,
            h : system.getRectangle().h
        };
        var space = 25;
        if (this.system.getSystemComplexity() > 1) {
            for (var i = 0; i < this.system.getChildren().length; i++) {
                var sub = this.system.getChildren()[i];
                var subRect = sub.getRectangle();
                if (subRect.x + subRect.w > fitSize.w - space) {
                    fitSize.w = subRect.x + subRect.w + space;
                }
                if (subRect.y + subRect.h > fitSize.h - space) {
                    fitSize.h = subRect.y + subRect.h + space + labelHeight;
                }
            }
        } else {
            var text = this.system.getValue();
            var ctx = _dss_editor._toolkit.getContext(canvas.entity);
            fitSize.w = ctx.measureText(text).width + space;
        }
        fitSize.w = fitSize.w > 120 ? fitSize.w : 120;
        fitSize.h = fitSize.h > 60 ? fitSize.h : 60;
        return fitSize;
    };

}
EditShowContentCommand.prototype = new DSCCommand();
EditShowContentCommand.prototype.execute = function() {
    this.system.setShowContent(this.showContent);
    // if (getValue(this.diagram.showInfo.showContent) == NO) {
    // this.diagram.showInfo.rectangle.h = 30;
    // }
    if (this.showContent === YES) {
        var fitSize = this.calculateFitSize(this.system);
        var fitRect = {
            x : this.system.getRectangle().x,
            y : this.system.getRectangle().y,
            w : fitSize.w,
            h : fitSize.h
        };
        this.system.setRectangle(fitRect);
    } else {
        var fitw = _dss_editor._toolkit.measureText(this.system.name);
        var fitRect = {
            x : this.system.getRectangle().x,
            y : this.system.getRectangle().y,
            w : fitw,
            h : this.system.getRectangle().h
        };
        this.system.setRectangle(fitRect);
    }
    this.setLinkVisible(this.system);
    // _dss_editor._command.cmdstack.push(this);
};
EditShowContentCommand.prototype.undoCommand = function(eventObj) {
    var canvas = eventObj.canvas;
    if (this.showContent === NO) {
        this.system.setShowContent(YES);
    } else {
        this.system.setShowContent(NO);
    }
    if (this.showContent === NO) {
        var fitSize = this.calculateFitSize(this.system);
        var fitRect = {
            x : this.system.getRectangle().x,
            y : this.system.getRectangle().y,
            w : fitSize.w,
            h : fitSize.h
        };
        this.system.setRectangle(fitRect);
    } else {
        var fitw = _dss_editor._toolkit.measureText(this.system.name);
        var fitRect = {
            x : this.system.getRectangle().x,
            y : this.system.getRectangle().y,
            w : fitw,
            h : this.system.getRectangle().h
        };
        this.system.setRectangle(fitRect);
    }
    this.setLinkVisible(this.system);
    _dss_editor._model.system.refreshSystemSelectionHandle(canvas);
};
EditShowContentCommand.prototype.redoCommand = function(eventObj){
	this.doCommand();
	_dss_editor._model.system.refreshSystemSelectionHandle(eventObj.canvas);
};

function CreateLinkCommand(linkType, canvas) {
    this.source = {};
    this.target = {};
    this.link = _dss_editor._model.link.create(linkType);
    this.isComplete = false;
    this.isFirst = false;
    //判断是第几次点击
    this.isNext = false;
    //判断是不是下一条连线
}
CreateLinkCommand.prototype = new DSCCommand();
CreateLinkCommand.prototype.execute = function() {
    if (this.isFirst) {
        // 完成创建连线
        var canvas = this.canvas;
        var point = this.pointTo;
        this.link.to = canvas.onDiagram.getFullName();
        this.link.showInfo.toAngle = _dss_editor._model.link.genAngle(canvas.onDiagram, point);
        canvas.addLink(this.link);
        _dss_editor._model.link.initLink({
            canvas : canvas,
            link : this.link
        });
        canvas.update();
        _dss_editor._command._commandsManager.undostack.pop();
        this.isFirst = false;
        this.isNext = true;
        this.isComplete = true;
    } else {
        // 开始创建连线
        var canvas = this.canvas;
        var point = this.pointFrom;
        if (canvas.onLink) {
            this.link.from = canvas.onLink.name;
        } else {
            this.link.from = canvas.onDiagram.getFullName();
            this.link.showInfo.fromAngle = _dss_editor._model.link.genAngle(canvas.onDiagram, point);
        }
        this.source = point;
        this.isFirst = true;
    }
	this.canvas = canvas;
};
CreateLinkCommand.prototype.undoCommand = function(eventObj) {
    this.link.fromSystem.removeLinkFrom(this.link);
    this.link.toSystem.removeLinkTo(this.link);
    this.link.clearHandles();
    this.canvas.removeLink(this.link);
};
CreateLinkCommand.prototype.redoCommand = function(eventObj) {
	this.link.fromSystem.addLinkFrom(this.link);
	this.link.toSystem.addLinkTo(this.link);
	this.canvas.addLink(this.link);
};

function ReconnectLinkCommand(link, canvas) {
    this.source = {};
    this.target = {};
    this.sourcePoint = {};
    this.targetPoint = {};
    this.link = link;
    this.canvas = canvas;
}
ReconnectLinkCommand.prototype = new DSCCommand();
ReconnectLinkCommand.prototype.execute = function() {
    this.link.showInfo.beforeFromAngle = _dss_editor._model.link.genAngle(this.source, this.sourcePoint);
    this.link.showInfo.beforeToAngle = _dss_editor._model.link.genAngle(this.target, this.targetPoint);

    if (this.link.getFromSystem() == this.source) {//说明重连的to
        this.link.beforeToSystem = this.link.getToSystem();
        this.link.getToSystem().removeLinkTo(this.link);
        this.target.addLinkTo(this.link);
    } else if (this.link.getToSystem() == this.target) {
        this.link.beforeFromSystem = this.link.getFromSystem();
        this.link.getFromSystem().removeLinkFrom(this.link);
        this.source.addLinkFrom(this.link);
    }
    this.link.showInfo.fromAngle = _dss_editor._model.link.genAngle(this.source, this.sourcePoint);
    this.link.showInfo.toAngle = _dss_editor._model.link.genAngle(this.target, this.targetPoint);

    this.canvas.addLink(this.link);
    this.canvas.update();
    this.isComplete = true;
    _dss_editor._model.link.refreshLinkSelectionHandle(this.canvas);
};
ReconnectLinkCommand.prototype.undoCommand = function(eventObj) {
    var canvas = eventObj.canvas;
    //delete
    this.link.fromSystem.removeLinkFrom(this.link);
    this.link.toSystem.removeLinkTo(this.link);
    this.link.clearHandles();
    this.canvas.removeLink(this.link);
    this.linkFrom = this.link.linkFrom;
    for (var i = 0; i < this.link.linkFrom.length; i++) {
        var l = this.link.linkFrom[i];
        this.canvas.removeLink(l);
    }
    //add
    this.link.showInfo.fromAngle = this.link.showInfo.beforeFromAngle;
    this.link.showInfo.toAngle = this.link.showInfo.beforeToAngle;
    this.link.setToSystem(this.link.beforeToSystem);
    this.link.setFromSystem(this.link.beforeFromSystem);
    for (var i = 0; i < this.link.linkFrom.length; i++) {
        var l = this.link.linkFrom[i];
        _dss_editor._model.link.initLink({
            canvas : canvas,
            link : l
        });
        canvas.addLink(l);
    }
    _dss_editor._model.link.initLink({
        canvas : canvas,
        link : this.link
    });
    canvas.addLink(this.link);
};
ReconnectLinkCommand.prototype.redoCommand = function(eventObj){
	this.doCommand();
};

function DeriveCommand(interaction, canvas) {
    this.interaction = interaction;
    this.canvas = canvas;
    this.parts = [];
    this.protocol = {};
    this.derivingLinks = [];
    this.parts.push(interaction.fromSystem);
    this.parts.push(interaction.toSystem);
    this.protocol = _dss_editor._toolkit.findSystemByName(this.canvas.baseSysForView.complete.sys.getChildren(), interaction.content);
    this.simpleDerive = function() {
        var fromSystem = this.interaction.getFromSystem();
        var toSystem = this.interaction.getToSystem();
        fromSystem.setDeriveFlag(SENDER);
        toSystem.setDeriveFlag(RECEIVER);
    };
    this.derive = function() {
        for (var i in this.parts) {
            var part = this.parts[i];
            this.derivePart(part);
        }
    };
    this.derivePart = function(part) {
        this.derivingLinks = [];
        var dir = part.name;
        part.setDeriveProtoName(this.interaction.content);
        part.setPartiProtoName(this.interaction.content);
        this.deriveLink(part, this.protocol);
        for (var i in this.protocol.getChildren()) {
            var pro = this.protocol.getChildren()[i];
            if (pro.getSystemComplexity() == 1) {
                this.deriveSimplePro(pro, dir, part);
            } else {
                this.deriveCompositePro(pro, dir, part);
            }
        }

    };

    this.createDeriveSys = function(parent) {
        var type = {};
        type.type = parent.getType();
        if (parent.hasOwnProperty('userDefinedType')) {
            type.type = parent.userDefinedType;
            type.baseOn = parent.getType();
        }
        return _dss_editor._model.system.createSystemByType(type);
    };
    this.getFullProName = function(pro) {
        var name = pro.name;
        while (pro != this.protocol && pro.hasOwnProperty('parent') && pro.parent.hasOwnProperty('name') && pro.parent != this.protocol) {
            name = pro.parent.name + '.' + name;
            pro = pro.parent;
        }
        return name;
    };
    // 一下2个方法都是符合交流中的2个derive的方法与简单交流的derive不同
    this.deriveSimplePro = function(pro, dir, parent) {
        var derived = null;
        var derivedName = pro.name;
        var deriveFlag = NOTDERIVE;
        //是接受者还是发送者
        if (dir == pro.getFrom()) {
            if (derivedName.charAt(derivedName.length - 1) == ']') {
                var index = derivedName.lastIndexOf('[');
                var i = derivedName.substr(index);
                var n = derivedName.substring(0, index);
                derivedName = n + '_s' + i;
            } else {
                derivedName = derivedName + '_s';
            }
            deriveFlag = SENDER;
        } else if (dir == pro.getTo()) {
            if (derivedName.charAt(derivedName.length - 1) == ']') {
                var index = derivedName.lastIndexOf('[');
                var i = derivedName.substr(index);
                var n = derivedName.substring(0, index);
                derivedName = n + '_r' + i;
            } else {
                derivedName = derivedName + '_r';
            }
            deriveFlag = RECEIVER;
        }
        for (var j in parent.getChildren()) {
            var sub = parent.getChildren()[j];
            if ((sub.name == derivedName || sub.getDeriveProtoName() == pro.name) && sub.getType() == parent.getType()) {
                derived = sub;
            }
        }
        if (!derived) {
            derived = this.createDeriveSys(parent);
            derived.name = derivedName;
            derived.setRectangle(pro.getRectangle());
            derived.setHasShadow(pro.hasShadow());
            parent.addChild(derived);
        }
        derived.setDeriveFlag(deriveFlag);
        derived.setDeriveProtoName(/*pro.name*/
        this.getFullProName(pro));
        derived.setPartiProtoName(this.interaction.content);
        this.deriveLink(derived, pro);
    };
    this.deriveCompositePro = function(pro, dir, parent) {
        var derived = null;
        var derivedName = pro.name;
        for (var j in parent.getChildren()) {
            var sub = parent.getChildren()[j];
            if ((sub.name == derivedName || sub.getDeriveProtoName() == pro.name) && sub.getType() == parent.getType()) {
                derived = sub;
            }
        }
        if (!derived) {
            derived = this.createDeriveSys(parent);
            derived.name = derivedName;
            derived.setRectangle(pro.getRectangle());
            derived.setHasShadow(pro.hasShadow());
            parent.addChild(derived);
        }
        derived.setDeriveFlag(NOTDERIVE);
        derived.setDeriveProtoName(this.getFullProName(pro));
        derived.setPartiProtoName(this.interaction.content);
        this.deriveLink(derived, pro);
        for (var i in pro.getChildren()) {
            var subPro = pro.getChildren()[i];
            if (subPro.style == POINT) {
                this.derivePoint(subPro, derived);
            } else if (subPro.style == SYSTEM) {
                if (subPro.getSystemComplexity() == 1) {
                    this.deriveSimplePro(subPro, dir, derived);
                } else {
                    this.deriveCompositePro(subPro, dir, derived);
                }
            }
        }
    };

    this.derivePoint = function(proPoint, parent) {
        if (parent.content.composite.hasOwnProperty('exitPoint')) {
            for (var i in parent.content.composite.exitPoint) {
                if (parent.content.composite.exitPoint[i].name == proPoint.name) {
                    return;
                }
            }
        }
        var derivePoint = _dss_editor._model.system.createPoint(proPoint.type);
        derivePoint.setRectangle(proPoint.getRectangle());
        derivePoint.name = proPoint.name;
        if (proPoint.type == EXITPOINT) {
            derivePoint.showInfo.angle = proPoint.showInfo.angle;
        }

        if (derivePoint != null) {
            parent.addChild(derivePoint);
        }
    };

    this.deriveLink = function(derived, pro) {
        for (var i in pro.getLinkFrom()) {
            var link = pro.getLinkFrom()[i];
            if (this.deriveLinkExisted(link, derived)) {
                continue;
            }
            if (link.deriving) {
                for (var j in this.derivingLinks) {
                    var derivingLink = this.derivingLinks[j];
                    if (derivingLink.proName == pro.getFullName()) {
                        //由于2个system可能互相有连线，那么derive的时候会造成link的proName一样的情况
                        if (derivingLink.fromSystem != null) {
                            continue;
                        }
                        derived.addLinkFrom(derivingLink);
                        this.canvas.addLink(derivingLink);
                        derivingLink.isDerived = YES;
                        _dss_editor._toolkit.removeArrayElement(this.derivingLinks, derivingLink);
                        // derivingLink.updateStatus();
                        _dss_editor._model.link.updateStatus.apply(derivingLink);
                        //break;
                    }
                }
                delete link.deriving;
            } else {
                link.deriving = true;
                var dLink = this.createDerivingLink(link);
                //dLink.setFromSystem(derived);
                derived.addLinkFrom(dLink);
                dLink.proName = link.toSystem.getFullName();
                this.derivingLinks.push(dLink);
            }
        }
        for (var i in pro.getLinkTo()) {
            var link = pro.getLinkTo()[i];
            if (this.deriveLinkExisted(link, derived)) {
                continue;
            }
            if (link.deriving) {
                for (var j in this.derivingLinks) {
                    var derivingLink = this.derivingLinks[j];
                    if (derivingLink.proName == pro.getFullName()) {
                        //						derivingLink.setToSystem(derived);
                        if (derivingLink.toSystem != null) {
                            continue;
                        }
                        derived.addLinkTo(derivingLink);
                        this.canvas.addLink(derivingLink);
                        _dss_editor._toolkit.removeArrayElement(this.derivingLinks, derivingLink);
                        derivingLink.isDerived = YES;
                       // derivingLink.updateStatus();
                        _dss_editor._model.link.updateStatus.apply(derivingLink);
                        //break;
                    }
                }
                delete link.deriving;
            } else {
                link.deriving = true;
                var dLink = this.createDerivingLink(link);
                //dLink.setToSystem(derived);
                derived.addLinkTo(dLink);
                dLink.proName = link.fromSystem.getFullName();
                this.derivingLinks.push(dLink);
            }
        }
    };

    this.createDerivingLink = function(proLink) {
        var dLink = LinkFractory.create(proLink.linkType);
        dLink.content = proLink.content;
        _dss_editor._model.link.initLink({
            canvas : this.canvas,
            link : dLink
        });
        dLink.showInfo.fromAngle = proLink.showInfo.fromAngle;
        dLink.showInfo.toAngle = proLink.showInfo.toAngle;
        return dLink;
    };

    this.deriveLinkExisted = function(proLink, derived) {
        var proName = derived.getDeriveProtoName();
        if (proName == this.getFullProName(proLink.getFromSystem())/*proLink.getFromSystem().name*/) {
            for (var i in derived.getLinkFrom()) {
                var link = derived.getLinkFrom()[i];
                // if(link.getToSystem() != null){
                // console.log('work:'+ link.getToSystem().getDeriveProtoName());
                // console.log('pro:' + this.getFullProName(proLink.getToSystem()));
                // console.log('--------------------------------------------------------');
                // }
                if (link.toSystem != null && link.toSystem.getDeriveProtoName() == this.getFullProName(proLink.toSystem)/*proLink.getToSystem().name*/) {
                    link.isDerived = 1;
                    return true;
                }
            }
        } else if (proName == this.getFullProName(proLink.getToSystem())/*proLink.getToSystem().name*/) {
            for (var i in derived.getLinkTo()) {
                var link = derived.getLinkTo()[i];
                if (link.fromSystem != null && link.fromSystem.getDeriveProtoName() == this.getFullProName(proLink.fromSystem)/*proLink.getFromSystem().name*/) {
                    link.isDerived = 1;
                    return true;
                }
            }
        }
        return false;
    };
}

DeriveCommand.prototype = new DSCCommand();
DeriveCommand.prototype.execute = function() {
    if (this.protocol == null || this.protocol.getSystemComplexity() == 1) {
        this.simpleDerive();
    } else {
        this.derive();
    }
};
DeriveCommand.prototype.undoCommand = function(eventObj) {

};

function ChangeTypeCommand() {
    this.type = {};
    this.system = {};
    // this.changeType = function(type) {
    // this.system.setType(type);
    // this.system.specSys = {};
    // };
    this.toSystem = function() {
        this.system.setType(_dss_editor._model.system._type.SYSTEM);
    };
    this.toWork = function() {
        this.system.setType(_dss_editor._model.system._type.WORK);
        this.system.specSys = {};
        this.system.specSys.work = {};
        this.system.specSys.work.deriveInfo = {};
        this.system.specSys.work.deriveInfo.deriveProtoName = '';
        this.system.specSys.work.deriveInfo.partiProtoName = '';
        this.system.specSys.work.deriveInfo.deriveFlag = NOTDERIVE + "," + SENDER + "," + RECEIVER + ";" + NOTDERIVE;
    };
    this.toData = function() {
        this.system.setType(_dss_editor._model.system._type.DATA);
        this.system.content = this.system.content || {};
        this.system.content.simple = this.system.content.simple || {};
        this.system.content.simple.expr = this.system.content.simple.expr || '';
        // if (this.system.content.hasOwnProperty('simple')) {
        // this.system.content.simple = 'Char,Integer,String,Real;' + this.system.content.simple;
        // }
    };
    this.toPredicate = function() {
        this.system.setType(_dss_editor._model.system._type.PREDICATE);
    };
    this.toProtocol = function() {
        this.system.setType(_dss_editor._model.system._type.PROTOCOL);
        this.system.specSys = {};
        this.system.specSys.protocol = {};
        this.system.specSys.protocol.simple = {};
        this.system.specSys.protocol.simple.from = '';
        this.system.specSys.protocol.simple.to = '';
        this.system.content = this.system.content || {};
        this.system.content.simple = this.system.content.simple || {};
        this.system.content.simple.expr = this.system.content.simple.expr || '';
        // if (this.system.content.hasOwnProperty('simple')) {
        // this.system.content.simple = 'Char,Integer,String,Real;' + this.system.content.simple;
        // }
    };
    this.toNameLabel = function() {
        var sysType = this.system.getType();
        this.system.setType(_dss_editor._model.system._type.NAMELABEL);
        this.specSys.nameLabel = _dss_editor._model.system._type.SYSTEM + "," + _dss_editor._model.system._type.WORK + "," + _dss_editor._model.system._type.DATA + "," + _dss_editor._model.system._type.PREDICATE + "," + _dss_editor._model.system._type.PROTOCOL + ";" + sysType;
    };

    this.toUserSystem = function() {
        this.toWork();
    };
}

ChangeTypeCommand.prototype = new DSCCommand();
ChangeTypeCommand.prototype.execute = function() {
    var type = this.type.type;
    var baseOn = this.type.baseOn;
    //这里仅仅处理了继承基本类型的情况，其他user type将另行处理
    if (baseOn != null) {
        this.system.userDefinedType = type;
        type = baseOn;
    }
    if (type == _dss_editor._model.system._type.SYSTEM) {
        this.toSystem();
    } else if (type == _dss_editor._model.system._type.WORK) {
        this.toWork();
    } else if (type == _dss_editor._model.system._type.DATA) {
        this.toData();
    } else if (type == _dss_editor._model.system._type.PREDICATE) {
        this.toPredicate();
    } else if (type == _dss_editor._model.system._type.PROTOCOL) {
        this.toProtocol();
    } else if (type == _dss_editor._model.system._type.NAMELABEL) {
        this.toNameLabel();
    } else if (type == COMMENT) {
        this.system.setType(type);
    }
};
ChangeTypeCommand.prototype.undoCommand = function(eventObj) {

};

function DrillCommand() {
    this.system = null;
    this.canvas = null;
    this.UP = 'up';
    this.DOWN = 'down';
    this.picked = null;
    this.createDrillView = function() {
        var links = _dss_editor._toolkit.getSystemAllInnerLinks(this.system);
        var subs = _dss_editor._toolkit.getSystemAllSubs(this.system);
        for (var i = 0; i < links.length; i++) {
            var link = links[i];
            if (link.getFromSystem() === this.system) {
                if ($.inArray(link.getFromSystem(), subs) === -1) {
                    links.splice(i, 1);
                    i--;
                }
            } else if (link.getToSystem() === this.system) {
                if (link.getFromSystem().style !== LINK && $.inArray(link.getFromSystem(), subs) === -1) {
                    links.splice(i, 1);
                    i--;
                }
            }
        }
        var sysForView = {
            complete : {
                sys : {
                    content : {
                        composite : {
                            subSys : [this.system]
                        }
                    }
                },
                links : links
            }
        };
        return sysForView;
    };
    this.updateCanvas = function() {
        this.canvas.removeSelectionSystem();
        var sysForView = this.createDrillView();
        this.canvas.links = sysForView.complete.links;
        this.canvas.sys = sysForView.complete.sys;
        this.canvas.sysForView = sysForView;
        _dss_editor._model.system.initSystemMethod(this.canvas.sys);
        this.canvas.sys.addChild = function(child) {
        };
        this.canvas.sys.removeChild = function(child) {
        };
        this.canvas.addSelectionSystem(this.system);
        //this.canvas.drillViews.push(this.system.getFullName());
        this.canvas.matchSize();
        this.canvas.update();
        this.canvas.entity.parentNode.scrollLeft = 0;
        this.canvas.entity.parentNode.scrollTop = 0;
    };
    //这是回到顶层之后回复canvas；
    this.restoreCanvas = function(canvas) {
        canvas.sysForView = canvas.baseSysForView;
        canvas.sys = canvas.sysForView.complete.sys;
        canvas.links = canvas.sysForView.complete.links;
        canvas.matchSize();
        canvas.update();
    };
    //drill down之前要恢复当前的system
    this.restoreSystem = function(system, canvas) {
        system.getRectangle = function() {
            var rectangle = null;
            if (this.hasOwnProperty('showInfo')) {
                if (this.showInfo.hasOwnProperty('rectangle')) {
                    rectangle = {};
                    this.showInfo.rectangle.h = this.showInfo.rectangle.h > _dss_editor._model.system.minSize.height ? this.showInfo.rectangle.h : _dss_editor._model.system.minSize.height;
                    this.showInfo.rectangle.w = this.showInfo.rectangle.w > _dss_editor._model.system.minSize.width ? this.showInfo.rectangle.w : _dss_editor._model.system.minSize.width;
                    rectangle.h = this.showInfo.rectangle.h;
                    rectangle.w = this.showInfo.rectangle.w;
                    rectangle.x = this.showInfo.rectangle.x;
                    rectangle.y = this.showInfo.rectangle.y;
                    if (getValue(this.showInfo.showContent) == NO) {
                        var fitw = _dss_editor._toolkit.measureText(this.name);
                        rectangle.h = 30;
                        rectangle.w = this.showInfo.rectangle.w;
                        rectangle.w = rectangle.w > _dss_editor._model.system.minSize.width ? rectangle.w : _dss_editor._model.system.minSize.width;
                        rectangle.w = rectangle.w > fitw ? rectangle.w : fitw;
                    }
                }
            }
            return rectangle;
        };

        system.setRectangle = function(rectangle) {
            this.showInfo.rectangle.x = rectangle.x;
            this.showInfo.rectangle.y = rectangle.y;
            this.showInfo.rectangle.h = rectangle.h;
            this.showInfo.rectangle.w = rectangle.w;
        };
        var conCmd = new EditShowContentCommand(system, NO);
        conCmd.doCommand();
        _dss_editor._model.system.refreshSystemSelectionHandle(canvas);
        delete system.isDrilling;
    };

    this.updateSystem = function() {
        if (this.system.drillBounds == null) {
            this.system.drillBounds = {
                x : 20,
                y : 40,
                w : this.system.showInfo.rectangle.w,
                h : this.system.showInfo.rectangle.h > 60 ? this.system.showInfo.rectangle.h : 60
            };
        }
        this.system.getRectangle = function() {
            var rectangle = null;
            if (this.hasOwnProperty('showInfo')) {
                if (this.showInfo.hasOwnProperty('rectangle')) {
                    rectangle = {};
                    rectangle.x = this.drillBounds.x;
                    rectangle.y = this.drillBounds.y;
                    rectangle.h = this.drillBounds.h;
                    rectangle.w = this.drillBounds.w;
                    if (getValue(this.showInfo.showContent) == NO) {
                        rectangle.h = 30;
                    }
                }
            }
            return rectangle;
        };

        this.system.setRectangle = function(rectangle) {
            this.drillBounds.x = rectangle.x;
            this.drillBounds.y = rectangle.y;
            this.drillBounds.h = rectangle.h;
            this.drillBounds.w = rectangle.w;
            this.showInfo.rectangle.h = rectangle.h;
            this.showInfo.rectangle.w = rectangle.w;
        };
        this.system.setRectangle(this.system.getRectangle());
        var conCmd = new EditShowContentCommand(this.system, YES);
        conCmd.doCommand();
        this.system.isDrilling = true;
        _dss_editor._model.system.refreshSystemSelectionHandle(this.canvas);
    };
    this.updateDrillList = function() {
        
        var canvas = this.canvas;
        var drillid = 'drillList' + canvas.entity.id;
        var drillList = $('#' + drillid);
        var aList = this.createHyper(this.system);
        var that = this;
        drillList.hide();
        //将不是drill的名字删除掉
        while (drillList.children().length > 0) {
            var childNode = drillList.children().eq(drillList.children().length - 1);
            if (childNode.attr('drillName')) {
                break;
            } else {
                childNode.remove();
            }
        }
        if (drillList.children().length == 0) {
            this.createTopHyper().appendTo(drillList);            
        }

        for (var i = 0; i < drillList.children().length; i++) {
            var a = drillList.children().eq(i);
            if (a.attr('drillName')) {
                a.attr('href', '#');
                a.click(function() {
                    that.upTo(this.id);
                });
            }
        }

        while (aList.length > 0) {
            var hyper = aList.pop();
            drillList.append(hyper);
            hyper.show();
        };
        drillList.show('fast');
    };

    this.createTopHyper = function() {
        var that = this;
        var id = 'top';
        var topHyper = $("<a/>", {
            html : "<<",
            href : "javascript:;",
            id : id
        });
        topHyper.click(function() {
            that.upTo(id);
        });
        return topHyper;
    };
    this.createHyper = function(system) {
        var parent = system.parent;
        var id = system.getFullName();
        var aList = [];
        var hyper = $("<a/>", {
            html : ' . ' + _dss_editor._model.system.getLabelText(system),
            drillName : id,
            id : id
        });
        aList.push(hyper);
        while (parent && parent.style != STYLE_ROOT && !parent.isDrilling) {
            var a = $("<a/>", {
                html : ' . ' + _dss_editor._model.system.getLabelText(parent)
            });
            aList.push(a);
            parent = parent.parent;
        }
        return aList;
    };

    this.down = function() {
        this.updateDrillList();
        this.updateSystem();
        this.updateCanvas();
    };

    this.upTo = function(id) {
        var parentNode = $('#drillList' + this.canvas.entity.id);
        var current = this.canvas.getCurrentDrillSystem();
        while (parentNode.children().length > 0) {
            var childNode = parentNode.children().eq(parentNode.children().length - 1);
            if (childNode.attr('drillName')) {
                this.system = _dss_editor._toolkit.findSystemByName(this.canvas.baseSysForView.complete.sys.getChildren(), childNode.attr('drillName'));
            }
            if (this.system.style == ARRAY) {
                for (var i in this.system.subInstance) {
                    var ins = this.system.subInstance[i];
                    if (' &gt; ' + _dss_editor._model.system.getLabelText(ins) == childNode.html()) {
                        this.system = ins;
                        break;
                    }
                }
            }
            this.restoreSystem(this.system, this.canvas);
            childNode.remove();
            if (childNode.attr('id') == id) {
                break;
            }
        }
        if (id == 'top') {
            this.restoreCanvas(this.canvas);
            parentNode.hide('fast');
        } else {
            this.down();
            if (current != null) {
                this.canvas.removeSelectionSystem();
                this.canvas.addSelectionSystem(current);
                this.canvas.update();
            }
        }
    };

    this.up = function() {
        var parentNode = $('#drillList' + this.canvas.entity.id);
        var i = 2;
        while (parentNode && parentNode.children().length >= i) {
            var upId = parentNode.children().eq(parentNode.children().length - i).attr("id");
            if (!upId) {
                i++;
                continue;
            } else {
                this.upTo(upId);
                break;
            }
        }
    };
}
DrillCommand.prototype = new DSCCommand();
DrillCommand.prototype.canExecute = function() {
    if(this.system && this.system.style !== SYSTEM){
        return false;
    }
    if (this.picked == this.DOWN && this.canvas != null && this.system != null && this.system.hasOwnProperty('isShowContent') && !this.system.isShowContent()) {
        return true;
    } else if (this.picked == this.UP) {
        var parentNode = $F('drillList' + this.canvas.entity.id);
        if (parentNode != null && parentNode.childNodes.length > 1) {
            return true;
        }
    }
    return false;
};
DrillCommand.prototype.execute = function() {
    if (this.picked == this.DOWN) {
        this.down();
    } else if (this.picked == this.UP) {
        this.up();
    }
};
DrillCommand.prototype.undoCommand = function(eventObj) {
    if (this.picked == this.DOWN) {
        this.up();
    } else if (this.picked == this.UP) {
        this.down();
    }
};
DrillCommand.prototype.redoCommand = function(eventObj) {
	this.doCommand();
};

function ExportSlideCommand(canvas) {
    this.canvas = canvas;
}

ExportSlideCommand.prototype = new DSCCommand();
ExportSlideCommand.prototype.execute = function() {
    var msg = stringifyToLocalSaveMessage(this.canvas);
    console.log(msg);
    // connectSaveServer('slide',msg);
    // _dss_editor.ws.send();
};

//------------------------------------
function ImportCommand(canvas) {
    this.canvas = canvas;
    this.getOffset = function() {
        var loc = {
            x : 20,
            y : 20
        };
        var space = 100;
        for (var i = 0; i < this.canvas.sys.getChildren().length; i++) {
            var system = this.canvas.sys.getChildren()[i];
            if (system.hasOwnProperty('getRectangle')) {
                var rect = system.getRectangle();
                if (rect.w + rect.x > loc.x - space) {
                    loc.x = rect.w + rect.x + space;
                }
                if (rect.h + rect.y > loc.y - space) {
                    loc.y = rect.h + rect.y + space;
                }
            } else if (system.style == ARRAY) {
                for (var j in system.subInstance) {
                    var ins = system.subInstance[j];
                    if (ins.isVisible()) {
                        var rect = ins.getRectangle();
                        if (rect.w + rect.x > loc.x - space) {
                            loc.x = rect.w + rect.x + space;
                        }
                        if (rect.h + rect.y > loc.y - space) {
                            loc.y = rect.h + rect.y + space;
                        }
                    }
                }
            }
        }
        return loc;
    };
}
ImportCommand.prototype = new DSCCommand();
ImportCommand.prototype.execute = function() {
    var contents = [];
    var that = this;
    var systems = [];
    var handler = function() {
        // console.log(content);
        for (var i = 0; i < contents.length; i++) {
            var content = contents[i];
            var offLoc = that.getOffset();
            try {
                var imported = JSON.parse(content);
                if (imported.complete.sys.content.composite.subSys) {
                    for (var j = 0; j < imported.complete.sys.content.composite.subSys.length; j++) {
                        var sub = imported.complete.sys.content.composite.subSys[j];
                        _dss_editor._model.system.initSystem(sub);
                        var rect = sub.getRectangle();
                        if (offLoc.x >= offLoc.y) {
                            rect.y += offLoc.y;
                        } else {
                            rect.x += offLoc.x;
                        }
                        sub.setRectangle(rect);
                        that.canvas.sysForView.complete.sys.addChild(sub);
                        systems.push(sub);
                    }
                }
                if (imported.complete.links) {
                    var branchLinks = [];
                    for (var j = 0; j < imported.complete.links.length; j++) {
                        var link = imported.complete.links[j];
                        if (_dss_editor._toolkit.findLinkByName(imported.complete.links, link.from)) {
                            branchLinks.push(link);
                        } else {
                            _dss_editor._model.link.initLink({
                                canvas : that.canvas,
                                link : link
                            });
                            that.canvas.addLink(link);
                        }

                    }

                    //暂时这样处理
                    for (var j = 0; j < branchLinks.length; j++) {
                        _dss_editor._model.link.initLink({
                            canvas : that.canvas,
                            link : branchLinks[j]
                        });
                        that.canvas.addLink(branchLinks[j]);
                    }
                }
            } catch(e) {
                console.error(e.stack);
                alert('import error');
            }
            that.canvas.update();
            $('#ds').dialog('destroy');
        };
	};
	this.contents = contents;
	var dialog = new DscDialog('ds', 'Input name', "<input type ='file' id='import' style='width:280px;padding:1px' value='' multiple />", handler);
	dialog.show();
	var imp = $('#import')[0];
	imp.onchange = function(e) {
		var files = imp.files;
		for (var i = 0; i < files.length; i++) {
			var file = files[i];
			var reader = new FileReader();
			e.preventDefault();
			reader.onload = function(eve) {
				contents.push(eve.target.result);
			};
			reader.readAsText(file);
		};
    };

    this.systems = systems;
};
ImportCommand.prototype.undoCommand = function(eventObj) {
    var canvas = eventObj.canvas;
    var systems = this.systems;
    for (var j = 0; j < systems.length; j++) {
        var system = this.systems[j];
        system.clearHandles();
        var links = _dss_editor._toolkit.getSystemAllInnerLinks(system);
        links = links.concat(system.getLinkFrom());
        links = links.concat(system.getLinkTo());
        for (var i in links) {
            var link = links[i];
            if (link) {
                link.fromSystem.removeLinkFrom(link);
                link.toSystem.removeLinkTo(link);
                link.clearHandles();
                canvas.removeLink(link);
            }
        }
        if (ArrayTool.isArrayInstance(system)) {
            system.parent.removeInstance(system);
        } else {
            system.parent.removeChild(system);
        }
    }
};
ImportCommand.prototype.redoCommand = function(eventObj){
	var contents = this.contents;
	var that = this;
			for (var i = 0; i < contents.length; i++) {
			var content = contents[i];
			var offLoc = that.getOffset();
			try {
				var imported = JSON.parse(content);
				if (imported.complete.sys.content.composite.subSys) {
					for (var j = 0; j < imported.complete.sys.content.composite.subSys.length; j++) {
						var sub = imported.complete.sys.content.composite.subSys[j];
						_dss_editor._model.system.initSystem(sub);
						var rect = sub.getRectangle();
						if (offLoc.x >= offLoc.y) {
							rect.y += offLoc.y;
						} else {
							rect.x += offLoc.x;
						}
						sub.setRectangle(rect);
						that.canvas.sysForView.complete.sys.addChild(sub);
					}
				}
				if (imported.complete.links) {
					var branchLinks = [];
					for (var j = 0; j < imported.complete.links.length; j++) {
						var link = imported.complete.links[j];
						if (_dss_editor._toolkit.findLinkByName(imported.complete.links, link.from)) {
							branchLinks.push(link);
						} else {
							_dss_editor._model.link.initLink({
								canvas : that.canvas,
								link : link
							});
							that.canvas.addLink(link);
						}

					}
					//暂时这样处理
					for (var j = 0; j < branchLinks.length; j++) {
						_dss_editor._model.link.initLink({
							canvas : that.canvas,
							link : branchLinks[j]
						});
						that.canvas.addLink(branchLinks[j]);
					}
				}
			} catch(e) {
				console.error(e.stack);
			}
		};
};

function ChangeSystemNameCommand (system, newText){
	this.system = system;
	this.oldText = system.getName();
	this.newText = newText;
}
ChangeSystemNameCommand.prototype = new DSCCommand();
ChangeSystemNameCommand.prototype.doCommand = function(){
	this.system.setName(this.newText);
};
ChangeSystemNameCommand.prototype.undoCommand = function(){
	this.system.setName(this.oldText);
};
ChangeSystemNameCommand.prototype.redoCommand = function(){
	this.system.setName(this.newText);
};

function ChangeSystemContentCommand (system, newValue){
	this.system = system;
	this.oldValue = system.getValue();
	this.newValue = newValue;
}
ChangeSystemContentCommand.prototype = new DSCCommand();
ChangeSystemContentCommand.prototype.doCommand = function (){
	this.system.setValue(this.newValue);
};
ChangeSystemContentCommand.prototype.undoCommand = function(){
	this.system.setValue(this.oldValue);
};
ChangeSystemContentCommand.prototype.redoCommand = function(){
	this.system.setValue(this.newValue);
};

function ChangeSystemArrayLengthCommand (system, newText){
	this.system = system;
	this.oldText = system.getStaticCnt();
	this.newText = newText;
}
ChangeSystemArrayLengthCommand.prototype = new DSCCommand();
ChangeSystemArrayLengthCommand.prototype.doCommand = function (){
	this.system.setStaticCnt(this.newText);
};
ChangeSystemArrayLengthCommand.prototype.undoCommand = function(){
	this.system.setStaticCnt(this.oldText);
};
ChangeSystemArrayLengthCommand.prototype.redoCommand = function(){
	this.system.setStaticCnt(this.newText);
};

function ChangeCommentTextCommand (system, newText){
	this.system = system;
	this.oldText = system.getValue();
	this.newText = newText;
}
ChangeCommentTextCommand.prototype = new DSCCommand();
ChangeCommentTextCommand.prototype.doCommand = function(){
	this.system.setValue(this.newText);
};
ChangeCommentTextCommand.prototype.undoCommand = function(){
	this.system.setValue(this.oldText);
};
ChangeCommentTextCommand.prototype.redoCommand = function(){
	this.system.setValue(this.newText);
};

function ChangeExitPointTextCommand (system, newText){
	this.system = system;
	this.oldText = system.name;
	this.newText = newText;
}
ChangeExitPointTextCommand.prototype = new DSCCommand();
ChangeExitPointTextCommand.prototype.doCommand = function(){
	this.system.name = this.newText;
};
ChangeExitPointTextCommand.prototype.undoCommand = function(){
	this.system.name = this.oldText;
};
ChangeExitPointTextCommand.prototype.redoCommand = function(){
	this.system.name = this.newText;
};

function ChangeLinkTextCommand(system, newText){
	this.system = system;
	this.oldText = system.content;
	this.newText = newText;
} 
ChangeLinkTextCommand.prototype = new DSCCommand();
ChangeLinkTextCommand.prototype.doCommand = function(){
	this.system.content = this.newText;
};
ChangeLinkTextCommand.prototype.undoCommand = function(){
	this.system.content = this.oldText;
};
ChangeLinkTextCommand.prototype.redoCommand = function(){
	this.system.content = this.newText;
};

function ChangeProDirTextCommand(system, newText){
	this.system = system;
	this.oldText = system.getFrom() + PRODIR + system.getTo();
	this.newText = newText;
}
ChangeProDirTextCommand.prototype = new DSCCommand();
ChangeProDirTextCommand.prototype.doCommand = function(){
	var dirIndex = this.newText.indexOf(PRODIR);
    if (dirIndex != -1) {
    	var from = this.newText.substring(0, dirIndex);
    	var to = this.newText.substring(dirIndex + 1, this.newText.length);
    	this.system.setFrom(from);
    	this.system.setTo(to);
    }
};
ChangeProDirTextCommand.prototype.undoCommand = function(){
	var dirIndex = this.oldText.indexOf(PRODIR);
    if (dirIndex != -1) {
    	var from = this.newText.substring(0, dirIndex);
    	var to = this.oldText.substring(dirIndex + 1, this.oldText.length);
    	this.system.setFrom(from);
    	this.system.setTo(to);
    }
};
ChangeProDirTextCommand.prototype.redoCommand = function(){
	var dirIndex = this.newText.indexOf(PRODIR);
    if (dirIndex != -1) {
    	var from = this.newText.substring(0, dirIndex);
    	var to = this.newText.substring(dirIndex + 1, this.newText.length);
    	this.system.setFrom(from);
    	this.system.setTo(to);
    }
};
